<?php

namespace unifiedpay\plugins;
use Exception;
use unifiedpay\plugins\lib\EpayCore;

require dirname(__FILE__)."/lib/EpayCore.php";

class Epay
{
	static public $info = [
		'name' => 'epay',
		'sort' => 4,
		'link' => 'https://user.9py.cn/',
		'types' => ['alipay', 'wechat', 'qpay'],
		'inputs' => [
			'apiurl' => [
				'name' => 'epay_apiurl',
				'type' => 'text',
				'note' => 'epay_apiurl_comment',
			],
			'pid' => [
				'name' => 'epay_pid',
				'type' => 'text',
				'note' => 'epay_pid_comment',
			],
			'key' => [
				'name' => 'epay_key',
				'type' => 'text',
				'note' => 'epay_key_comment',
			],
			'mapi' => [
				'name' => 'epay_mapi',
				'type' => 'radio',
				'note' => 'epay_mapi_comment',
			],
		],
	];

	public $channel;
	private $settings;
	public function __construct() {
		global $_G;
		$this->settings = $this->getConfig();
	}

	private function getConfig() {
		$settings = \C::t('common_setting')->fetch_setting('unifiedpay_epay', true);
		return $settings;
	}

	public function pay($order) {
		global $_G;
		\C::t('common_payment_order')->update($order['id'], array('channel' => $this->channel, 'plugin' => 'epay'));
		$type = $this->channel;
		if($type == 'wechat') $type = 'wxpay';
		else if($type == 'qpay') $type = 'qqpay';
		if($this->settings['mapi'] == 1) {
			return $this->epay_mapi($type, $order);
		} else {
			return $this->epay_submit($type, $order);
		}
		return array('code' => 500, 'message' => 'Did not open payment');
	}

	private function epay_submit($type, $order) {
		global $_G;

		if(strtoupper($_G['charset'] != 'UTF-8')) {
			$order['subject'] = diconv($order['subject'], $_G['charset'], 'UTF-8');
		}

		$params = [
			'pid' => $this->settings['pid'],
			'type' => $type,
			'notify_url' => $_G['siteurl'] . 'api/payment/notify/notify_epay.php',
			'return_url' => $_G['siteurl'] . 'api/payment/notify/return_epay.php',
			'out_trade_no' => $order['out_biz_no'],
			'name' => $order['subject'],
			'money' => sprintf('%.2f', $order['amount'] / 100),
		];
		$epay = new EpayCore($this->settings);
		$html_text = $epay->pagePay($params);
		return array('code' => 200, 'type' => 'html', 'url' => $html_text);
	}

	private function epay_mapi($type, $order) {
		global $_G;

		if(strtoupper($_G['charset'] != 'UTF-8')) {
			$order['subject'] = diconv($order['subject'], $_G['charset'], 'UTF-8');
		}

		$params = [
			'pid' => $this->settings['pid'],
			'type' => $type,
			'device' => EpayCore::getDevice(),
			'clientip' => $_G['clientip'],
			'notify_url' => $_G['siteurl'] . 'api/payment/notify/notify_epay.php',
			'return_url' => $_G['siteurl'] . 'api/payment/notify/return_epay.php',
			'out_trade_no' => $order['out_biz_no'],
			'name' => $order['subject'],
			'money' => sprintf('%.2f', $order['amount'] / 100),
		];
		$epay = new EpayCore($this->settings);
		$result = $epay->apiPay($params);
		if(isset($result['code']) && $result['code']==1){
			if($result['payurl']){
				$method = 'jump';
				$url = $result['payurl'];
			}elseif($result['qrcode']){
				$method = 'qrcode';
				$url = $result['qrcode'];
			}elseif($result['urlscheme']){
				$method = 'scheme';
				$url = $result['urlscheme'];
			}else{
				return array('code' => 501, 'message' => '未返回支付链接');
			}
		}elseif(isset($result['msg'])){
			return array('code' => 501, 'message' => $result['msg']);
		}else{
			return array('code' => 501, 'message' => '获取支付接口数据失败');
		}
		return array('code' => 200, 'type' => $method, 'url' => $url);
	}

	public function status($out_biz_no) {
		$epay = new EpayCore($this->settings);
		$result = $epay->queryOrder($out_biz_no);
		if(isset($result['code']) && $result['code']==1){
			if($result['status'] > 0) {
				return array('code' => 200, 'data' => array('trade_no' => $result['trade_no'], 'payment_time' => strtotime($result['endtime'])));
			}else{
				return array('code' => 500, 'message' => '未支付');
			}
		}else{
			return array('code' => 501, 'message' => $result['msg']);
		}
	}

	public function refund($refund_no, $trade_no, $total_amount, $refund_amount, $refund_desc) {
		$epay = new EpayCore($this->settings);
		$result = $epay->refund($trade_no, sprintf('%.2f', $refund_amount / 100));
		if(isset($result['code']) && $result['code']==1){
			return array('code' => 200, 'data' => array('refund_time' => time()));
		}else{
			return array('code' => 501, 'message' => $result['msg']);
		}
	}

	public function refund_status($refund_no, $trade_no) {
		return array('code' => 200, 'data' => array('refund_time' => time()));
	}

	public function notify() {
		if(!$_GET['sign'] || !$_GET['type']) {
			exit('fail');
		}

		$epay = new EpayCore($this->settings);
		$verify_result = $epay->verifyNotify();
		if(!$verify_result) {
			exit('sign_fail');
		}
		
		if($_GET['trade_status'] == 'TRADE_SUCCESS') {
			$out_biz_no = $_GET['out_trade_no'];
		
			unifiedpay_process_notify($out_biz_no, $_GET['trade_no']);
			exit('success');
		}
		
		exit('fail');
	}

	public function return(){
		if(!$_GET['sign'] || !$_GET['type']) {
			showmessage('unifiedpay:parameter_incomplete', '', array(), array('showdialog' => true));
		}

		$epay = new EpayCore($this->settings);
		$verify_result = $epay->verifyReturn();
		if(!$verify_result) {
			showmessage('unifiedpay:sign_verify_failed', '', array(), array('showdialog' => true));
		}

		if($_GET['trade_status'] == 'TRADE_SUCCESS') {
			$out_biz_no = $_GET['out_trade_no'];
		
			unifiedpay_process_return($out_biz_no, $_GET['trade_no']);
		}else{
			showmessage('unifiedpay:payment_failed', '', array(), array('showdialog' => true));
		}
	}
}